From: Nicolas BESNARD Date: Tue, 19 Nov 2024 12:46:22 +0000 (+0000) Subject: ubus: implement UBus method to get state data immediately X-Git-Url: http://git.openwrt.org/%22https:/collectd.org//%22%24PHP_SELF/%22https:/collectd.org/%22%24PHP_SELF?a=commitdiff_plain;h=3a1a599fecb7b06f1a6847d5a4dc44c886c12f81;p=project%2Fodhcp6c.git ubus: implement UBus method to get state data immediately Problem: odhcp6c state data are transmitted when the DHCPv6 state changes. If a process subscribes after the start of odhcp6c, then it has to wait for the next update event. Solution: Add a new UBus method "get_state" to get the latest state data immediately. Signed-off-by: Nicolas BESNARD Signed-off-by: Paul Donald Link: https://github.com/openwrt/odhcp6c/pull/106 Signed-off-by: Álvaro Fernández Rojas --- diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 9d4081a..9637ada 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -209,6 +209,83 @@ static char *dhcpv6_status_code_to_str(uint16_t code) return "Unknown"; } +const char *dhcpv6_state_to_str(enum dhcpv6_state state) +{ + switch (state) { + case DHCPV6_INIT: + return "INIT"; + + case DHCPV6_SOLICIT: + return "SOLICIT"; + + case DHCPV6_SOLICIT_PROCESSING: + return "SOLICIT_PROCESSING"; + + case DHCPV6_ADVERT: + return "ADVERT"; + + case DHCPV6_REQUEST: + return "REQUEST"; + + case DHCPV6_REQUEST_PROCESSING: + return "REQUEST_PROCESSING"; + + case DHCPV6_REPLY: + return "REPLY"; + + case DHCPV6_BOUND: + return "BOUND"; + + case DHCPV6_BOUND_PROCESSING: + return "BOUND_PROCESSING"; + + case DHCPV6_BOUND_REPLY: + return "BOUND_REPLY"; + + case DHCPV6_RECONF: + return "RECONF"; + + case DHCPV6_RECONF_PROCESSING: + return "RECONF_PROCESSING"; + + case DHCPV6_RECONF_REPLY: + return "RECONF_REPLY"; + + case DHCPV6_RENEW: + return "RENEW"; + + case DHCPV6_RENEW_PROCESSING: + return "RENEW_PROCESSING"; + + case DHCPV6_RENEW_REPLY: + return "RENEW_REPLY"; + + case DHCPV6_REBIND: + return "REBIND"; + + case DHCPV6_REBIND_PROCESSING: + return "REBIND_PROCESSING"; + + case DHCPV6_REBIND_REPLY: + return "REBIND_REPLY"; + + case DHCPV6_INFO: + return "INFO"; + + case DHCPV6_INFO_PROCESSING: + return "INFO_PROCESSING"; + + case DHCPV6_INFO_REPLY: + return "INFO_REPLY"; + + case DHCPV6_EXIT: + return "EXIT"; + + default: + return "INVALID_STATE"; + } +} + static int fd_set_nonblocking(int sockfd) { int flags = fcntl(sockfd, F_GETFL, 0); diff --git a/src/odhcp6c.h b/src/odhcp6c.h index 0f1692a..a28decc 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -441,6 +441,7 @@ int dhcpv6_state_processing(enum dhcpv6_msg type); int dhcpv6_get_state_timeout(void); void dhcpv6_set_state_timeout(int timeout); void dhcpv6_reset_state_timeout(void); +const char *dhcpv6_state_to_str(enum dhcpv6_state state); int init_rtnetlink(void); int set_rtnetlink_addr(int ifindex, const struct in6_addr *addr, diff --git a/src/ubus.c b/src/ubus.c index c369e7d..ebe16ae 100644 --- a/src/ubus.c +++ b/src/ubus.c @@ -104,10 +104,13 @@ static char ubus_name[24]; static int ubus_handle_get_state(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg); -static struct ubus_object_type odhcp6c_object_type = { - .name = "odhcp6c" +static struct ubus_method odhcp6c_object_methods[] = { + UBUS_METHOD_NOARG("get_state", ubus_handle_get_state), }; +static struct ubus_object_type odhcp6c_object_type = + UBUS_OBJECT_TYPE("odhcp6c", odhcp6c_object_methods); + static struct ubus_object odhcp6c_object = { .name = NULL, .type = &odhcp6c_object_type, @@ -452,13 +455,9 @@ static int s46_to_blob(enum odhcp6c_state state, const uint8_t *data, size_t len return UBUS_STATUS_OK; } -int ubus_dhcp_event(const char* status) +static int states_to_blob(void) { - if (!ubus || !odhcp6c_object.has_subscribers) - return UBUS_STATUS_UNKNOWN_ERROR; - char *buf = NULL; - size_t dns_len, search_len, custom_len, sntp_ip_len, ntp_ip_len, ntp_dns_len; size_t sip_ip_len, sip_fqdn_len, aftr_name_len, cer_len, addr_len; size_t s46_mapt_len, s46_mape_len, s46_lw_len, passthru_len; @@ -489,6 +488,8 @@ int ubus_dhcp_event(const char* status) blob_buf_init(&b, BLOBMSG_TYPE_TABLE); + blobmsg_add_string(&b, "DHCPV6_STATE", dhcpv6_state_to_str(dhcpv6_get_state())); + CHECK(ipv6_to_blob("SERVER", addr, addr_len / sizeof(*addr))); CHECK(ipv6_to_blob("RDNSS", dns, dns_len / sizeof(*dns))); CHECK(ipv6_to_blob("SNTP_IP", sntp, sntp_ip_len / sizeof(*sntp))); @@ -523,6 +524,27 @@ int ubus_dhcp_event(const char* status) CHECK_ALLOC(buf); script_hexlify(buf, passthru, passthru_len); blobmsg_add_string_buffer(&b); + + return UBUS_STATUS_OK; +} + +static int ubus_handle_get_state(struct ubus_context *ctx, _unused struct ubus_object *obj, + struct ubus_request_data *req, _unused const char *method, + _unused struct blob_attr *msg) +{ + CHECK(states_to_blob()); + CHECK(ubus_send_reply(ctx, req, b.head)); + blob_buf_free(&b); + + return UBUS_STATUS_OK; +} + +int ubus_dhcp_event(const char *status) +{ + if (!ubus || !odhcp6c_object.has_subscribers) + return UBUS_STATUS_UNKNOWN_ERROR; + + CHECK(states_to_blob()); CHECK(ubus_notify(ubus, &odhcp6c_object, status, b.head, -1)); blob_buf_free(&b);